/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package bpel2rep.version.impl;

import bpel2rep.exception.DuplicateVersionException;
import bpel2rep.exception.UnknownStateNameException;
import bpel2rep.process.util.ProcessId;
import bpel2rep.util.UnoptimizedDeepCopy;
import bpel2rep.version.*;
import bpel2rep.version.state.StateFactory;
import bpel2rep.version.store.StoreFactory;
import bpel2rep.version.store.TeneoStore;
import bpel2rep.version.util.VersionIdUtil;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;

import org.eclipse.emf.ecore.impl.EFactoryImpl;

import org.eclipse.emf.ecore.plugin.EcorePlugin;

import executable.TProcess;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model <b>Factory</b>.
 * <!-- end-user-doc -->
 * @generated
 */
public class VersionFactoryImpl extends EFactoryImpl implements VersionFactory {
	/**
	 * Creates the default factory implementation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public static VersionFactory init() {
		try {
			VersionFactory theVersionFactory = (VersionFactory)EPackage.Registry.INSTANCE.getEFactory("http://de.tiw.bpel2resp.version"); 
			if (theVersionFactory != null) {
				return theVersionFactory;
			}
		}
		catch (Exception exception) {
			EcorePlugin.INSTANCE.log(exception);
		}
		return new VersionFactoryImpl();
	}

	/**
	 * Creates an instance of the factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public VersionFactoryImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EObject create(EClass eClass) {
		switch (eClass.getClassifierID()) {
			case VersionPackage.META_INFO: return createMetaInfo();
			case VersionPackage.VERSION: return createVersion();
			case VersionPackage.VERSION_ID: return createVersionId();
			case VersionPackage.WORKING_STATUS: return createWorkingStatus();
			default:
				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object createFromString(EDataType eDataType, String initialValue) {
		switch (eDataType.getClassifierID()) {
			case VersionPackage.STATE_NAME:
				return createStateNameFromString(eDataType, initialValue);
			case VersionPackage.STATUS_NAME:
				return createStatusNameFromString(eDataType, initialValue);
			default:
				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String convertToString(EDataType eDataType, Object instanceValue) {
		switch (eDataType.getClassifierID()) {
			case VersionPackage.STATE_NAME:
				return convertStateNameToString(eDataType, instanceValue);
			case VersionPackage.STATUS_NAME:
				return convertStatusNameToString(eDataType, instanceValue);
			default:
				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public MetaInfo createMetaInfo() {
		MetaInfoImpl metaInfo = new MetaInfoImpl();
		return metaInfo;
	}



	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Version createVersion() {
		VersionImpl version = new VersionImpl();
		return version;
	}

	public Version createVersion(VersionStore vs){
		VersionImpl version = new VersionImpl(vs);
		return version;
	}
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public VersionId createVersionId() {
		VersionIdImpl versionId = new VersionIdImpl();
		return versionId;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public WorkingStatus createWorkingStatus() {
		WorkingStatusImpl workingStatus = new WorkingStatusImpl();
		return workingStatus;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StateName createStateNameFromString(EDataType eDataType, String initialValue) {
		StateName result = StateName.get(initialValue);
		if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'");
		return result;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String convertStateNameToString(EDataType eDataType, Object instanceValue) {
		return instanceValue == null ? null : instanceValue.toString();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public StatusName createStatusNameFromString(EDataType eDataType, String initialValue) {
		StatusName result = StatusName.get(initialValue);
		if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'");
		return result;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String convertStatusNameToString(EDataType eDataType, Object instanceValue) {
		return instanceValue == null ? null : instanceValue.toString();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public VersionPackage getVersionPackage() {
		return (VersionPackage)getEPackage();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @deprecated
	 * @generated
	 */
	@Deprecated
	public static VersionPackage getPackage() {
		return VersionPackage.eINSTANCE;
	}
	
	/**
	 * create the frist versionid
	 * @return initial versionid
	 */
	private VersionId initVersionId() {
		VersionIdImpl versionId = new VersionIdImpl();
		versionId.setMajorID(1);
		versionId.setMinorID(0);
		return versionId;
	}
	
	public Version initVersion(TProcess tp, MetaInfo info) {
		String processID = ProcessId.create();
		
		bpel2rep.version.store.StoreFactory f = bpel2rep.version.store.StoreFactory.eINSTANCE;
		TeneoStore ts = f.createTeneoStore();
		
		Version v = this.createVersion(ts);
		bpel2rep.process.ProcessFactory processFactory = bpel2rep.process.ProcessFactory.eINSTANCE;
		bpel2rep.process.Process process = processFactory.createProcess(tp,
				processID);
		v.setProcess(process);

		VersionId proVersion = this.createVersionId();
		v.setPredecessor(proVersion);

//		MetaInfo mi = VersionFactory.eINSTANCE.createMetaInfo();
//		mi.setDescription("dummy description for the first version");
//		mi.setId("123");
//		mi.setName("first Version");
		v.setMetaInfo(info);


		try {
			v.setStateName(StateName.INITIAL);
		} catch (UnknownStateNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		v.setVersionState(v.getInitialState());
//		System.out.println("ini version: the state of version is: " + v.getVersionState().getClass().toString());
		VersionId vid = this.initVersionId();
		v.setVersionId(vid);

		// v.getClass().toString();
		return v;
	}

	// 1. find out whether the version is already in the repository
	// 2. increase the version number
	// 3. set the version id of the predecessor into predecessorId
	// 4. return modified version
	public Version nextVersion(Version version, boolean isMajor) throws DuplicateVersionException {
		Version v = VersionFactory.eINSTANCE.createVersion();
		TeneoStore ts = StoreFactory.eINSTANCE.createTeneoStore();
		Version vclone = (Version) UnoptimizedDeepCopy.copy(version);
		// if the version is already in the store, then update this version
		if(ts.inStore(version)){
			VersionId proVerisonId = vclone.getVersionId();
			VersionId newVersionId = VersionIdUtil.increaseVersion(proVerisonId, isMajor);
			vclone.setPredecessor(proVerisonId);
			vclone.setVersionId(newVersionId);
		}else{
			v = this.initVersion(version.getProcess().getTprocess(), version.getMetaInfo());
		}
		return v;
	}




} //VersionFactoryImpl
